﻿using System;
using System.IO;
using System.Runtime.InteropServices;

using Microsoft.Win32;

namespace WebServer
{
	/// <summary>
	/// Utility class contains static method checkType to determine MimeType
	/// </summary>
	public class MimeTypeUtil
	{
		[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
		private extern static UInt32 FindMimeFromData
		(
			UInt32 pBC,
			[MarshalAs(UnmanagedType.LPStr)] String pwzUrl,
			[MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
			UInt32 cbSize,
			[MarshalAs(UnmanagedType.LPStr)] String pwzMimeProposed,
			UInt32 dwMimeFlags,
			out UInt32 ppwzMimeOut,
			UInt32 dwReserved
		);

		/// <summary>
		/// Attempts to retrieve the MIME-Type information for a file
		/// </summary>
		/// <param name="filePath">Path to the file</param>
		/// <returns>MIME Type</returns>
		public static string Get(string filePath)
		{
			string fromRegistry = GetFromRegistry(filePath);

			if (!String.IsNullOrEmpty(fromRegistry))
				return fromRegistry;

			try
			{
				byte[] buffer = new byte[256];

				using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
				{
					if (fileStream.Length >= 256)
						fileStream.Read(buffer, 0, 256);
					else
						fileStream.Read(buffer, 0, (int)fileStream.Length);
				}

				System.UInt32 mimeType;
				System.UInt32 returnValue = FindMimeFromData(0, null, buffer, 256, null, 0, out mimeType, 0);
				System.IntPtr mimeTypePointer = new IntPtr(mimeType);

				return Marshal.PtrToStringUni(mimeTypePointer);
			}
			catch (Exception ex) { return ex.ToString(); }
		}

		/// <summary>
		/// Attempts to retrieve the MIME-Type information for a file from the Win32 Registry
		/// </summary>
		/// <param name="filePath">File to check</param>
		/// <returns>MIME-Type or String.Empty if not found</returns>
		public static string GetFromRegistry(string filePath)
		{
			string mime = String.Empty; //"application/octetstream";
			string ext = Path.GetExtension(filePath).ToLower();
			RegistryKey rk = Registry.ClassesRoot.OpenSubKey(ext);

			if (rk != null && rk.GetValue("Content Type") != null)
				mime = rk.GetValue("Content Type").ToString();

			return mime;
		}
	}
}